/*
 * Copyright (C) 2013 Daniel Wasilew <daniel.wasilew@codeminer.org>
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
package org.codeminer.parts.database.dao;

import java.util.Collections;
import java.util.EnumSet;
import java.util.List;
import java.util.Set;
import org.codeminer.database.DatabaseConnection;
import org.codeminer.database.DatabaseException;
import org.codeminer.parts.database.sql.SQL;
import org.codeminer.parts.server.permissions.Permission;
import org.codeminer.parts.server.users.User;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 *
 * @author Daniel Wasilew <daniel.wasilew@codeminer.org>
 */
public final class PermissionsDAO extends DAO {

    private static final Logger log = LoggerFactory.getLogger(PermissionsDAO.class);
    private static final String TABLE_NAME = "USER_PERMISSIONS";
    private static final String USER_COLUMN_NAME = "User_Id";
    private static final String PERMISSION_COLUMN_NAME = "Permission_Value";

    public static void setPermissions(User user, Set<Permission> permissions, DatabaseConnection connection) {
        final Set<Permission> current = get(user, connection);
        permissions.removeAll(current);
        if (permissions.isEmpty()) {
            return;
        }
        try {
            connection.accuireWriteLock();
            for (Permission permission : permissions) {
                final String insert = SQL.insertInto(TABLE_NAME).values().value(user.getName()).value(permission.name()).toSQL();
                executeInsert(connection, insert);
            }
        } catch (DatabaseException ex) {
            log.error("could not store permissions for user", ex);
        } finally {
            connection.releaseWriteLock();
        }
    }

    public static Set<Permission> get(User user, DatabaseConnection connection) {
        final String sql = SQL.select(PERMISSION_COLUMN_NAME).from(TABLE_NAME).where(USER_COLUMN_NAME).is(user.getName()).toSQL();
        try {
            connection.accuireReadLock();
            List<String> tmp = getPropertyList(sql, PERMISSION_COLUMN_NAME, connection);
            Set<Permission> result = EnumSet.noneOf(Permission.class);
            for (String value : tmp) {
                result.add(Permission.valueOf(value));
            }
            return result;
        } catch (DatabaseException ex) {
            log.error("could not get permissions for user", ex);
            return Collections.emptySet();
        } finally {
            connection.releaseReadLock();
        }
    }

    public static void removePermission(User user, Permission permission, DatabaseConnection connection) {
        final String delete = SQL.delete().from(TABLE_NAME).where(USER_COLUMN_NAME).is(user.getName()).and(PERMISSION_COLUMN_NAME).is(permission.name()).toSQL();
        try {
            connection.accuireWriteLock();
            executeUpdate(connection, delete);
        } catch (DatabaseException ex) {
            log.error("could not remove permission", ex);
        } finally {
            connection.releaseWriteLock();
        }
    }

    private PermissionsDAO() {
    }
}
